#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

struct Point {
    int x, y, idx;
    Point(int x = 0, int y = 0, int idx = 0) : x(x), y(y), idx(idx) {}
};

// 计算按某种排序方式配对后的总曼哈顿距离
long long calculateSum(const vector<Point>& sorted_points) {
    int n = sorted_points.size();
    long long sum = 0;
    for (int i = 0; i < n / 2; ++i) {
        int j = n - 1 - i;
        sum += abs(sorted_points[i].x - sorted_points[j].x) + 
               abs(sorted_points[i].y - sorted_points[j].y);
    }
    return sum;
}

void solve() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<Point> points;
        for (int i = 0; i < n; ++i) {
            int x, y;
            cin >> x >> y;
            points.emplace_back(x, y, i + 1); // 存储原始索引（1-based）
        }
        
        // 生成四种可能的排序方式及其对应的距离总和
        vector<pair<long long, vector<Point>>> candidates;
        
        // 按x坐标排序
        vector<Point> sorted_x = points;
        sort(sorted_x.begin(), sorted_x.end(), [](const Point& a, const Point& b) {
            return a.x < b.x;
        });
        candidates.emplace_back(calculateSum(sorted_x), sorted_x);
        
        // 按y坐标排序
        vector<Point> sorted_y = points;
        sort(sorted_y.begin(), sorted_y.end(), [](const Point& a, const Point& b) {
            return a.y < b.y;
        });
        candidates.emplace_back(calculateSum(sorted_y), sorted_y);
        
        // 按x + y排序
        vector<Point> sorted_x_plus_y = points;
        sort(sorted_x_plus_y.begin(), sorted_x_plus_y.end(), [](const Point& a, const Point& b) {
            return (a.x + a.y) < (b.x + b.y);
        });
        candidates.emplace_back(calculateSum(sorted_x_plus_y), sorted_x_plus_y);
        
        // 按x - y排序
        vector<Point> sorted_x_minus_y = points;
        sort(sorted_x_minus_y.begin(), sorted_x_minus_y.end(), [](const Point& a, const Point& b) {
            return (a.x - a.y) < (b.x - b.y);
        });
        candidates.emplace_back(calculateSum(sorted_x_minus_y), sorted_x_minus_y);
        
        // 找到总距离最大的排序方式
        auto best = max_element(candidates.begin(), candidates.end(),
            [](const pair<long long, vector<Point>>& a, const pair<long long, vector<Point>>& b) {
                return a.first < b.first;
            });
        
        // 输出最优配对的索引
        const vector<Point>& best_order = best->second;
        for (int i = 0; i < n / 2; ++i) {
            int j = n - 1 - i;
            cout << best_order[i].idx << " " << best_order[j].idx << "\n";
        }
    }
}

int main() {
    solve();
    return 0;
}